﻿using System.Windows;
using System.Windows.Input;

namespace Monti.MVVM
{
   /// <summary>
   /// Base for a window view model.
   /// </summary>
   public class MainWindowViewModelBase : ViewModelBase
   {
      #region Fields

      private DialogBase m_DialogContent;
      private Visibility m_DialogVisibility;
      private RelayCommand m_CmdDialogOk;
      private RelayCommand m_CmdDialogYes;
      private RelayCommand m_CmdDialogNo;
      private RelayCommand m_CmdDialogCancel;

      #endregion

      #region Properties

      /// <summary>
      /// Gets or sets the dialog visibility.
      /// </summary>
      public Visibility DialogVisibility
      {
         get { return this.m_DialogVisibility; }
         set
         {
            if (value == Visibility.Collapsed && this.DialogContent != null)
            {
               this.DialogContent.RaiseClosingEvent ();
               if (!this.DialogContent.OkToClose)
                  return;
            }
            this.m_DialogVisibility = value;
            this.RaisePropertyChanged ("DialogVisibility");
         }
      }

      /// <summary>
      /// Gets or Sets the Dialog content.
      /// </summary>
      public DialogBase DialogContent
      {
         get { return this.m_DialogContent; }
         set
         {
            if (value == null && this.m_DialogContent != null)
            {
               this.DialogContent.RaiseClosingEvent ();
               if (!this.DialogContent.OkToClose)
                  return;
            }
            this.m_DialogContent = value;
            this.DialogVisibility = this.m_DialogContent == null ? Visibility.Collapsed : Visibility.Visible;
            this.RaisePropertyChanged ("DialogContent");
         }
      }

      /// <summary>
      /// Gets the command for when the dialog ok button is pressed.
      /// </summary>
      public ICommand DialogOkCommand
      {
         get { return this.m_CmdDialogOk ?? (this.m_CmdDialogOk = new RelayCommand (DialogOk, DialogCanOk)); }
      }

      /// <summary>
      /// Gets the command for when the dialog yes button is pressed.
      /// </summary>
      public ICommand DialogYesCommand
      {
         get { return this.m_CmdDialogYes ?? (this.m_CmdDialogYes = new RelayCommand (DialogYes, DialogCanYes)); }
      }

      /// <summary>
      /// Gets the command for when the dialog no button is pressed.
      /// </summary>
      public ICommand DialogNoCommand
      {
         get { return this.m_CmdDialogNo ?? (this.m_CmdDialogNo = new RelayCommand (DialogNo, DialogCanNo)); }
      }

      /// <summary>
      /// Gets the command for when the dialog ok button is pressed.
      /// </summary>
      public ICommand DialogCancelCommand
      {
         get { return this.m_CmdDialogCancel ?? (this.m_CmdDialogCancel = new RelayCommand (DialogCancel, DialogCanCancel)); }
      }

      #endregion

      #region Methods

      /// <summary>
      /// Checks if the dialog ok button command can be executed.
      /// </summary>
      /// <param name="parameter">Command parameter.</param>
      /// <returns>If the command can be executed or not.</returns>
      protected virtual bool DialogCanOk (object parameter)
      {
         if (this.DialogContent != null)
            return this.DialogContent.CanOkExecute ();
         return true;
      }

      /// <summary>
      /// Occurs when the ok button is pressed on the dialog.
      /// </summary>
      /// <param name="parameter">Command parameter.</param>
      protected virtual void DialogOk (object parameter)
      {
         if (this.DialogContent != null)
         {
            this.DialogContent.OkExecuted ();
            if (this.DialogContent.OkToClose)
               this.DialogVisibility = Visibility.Collapsed;
         }
      }

      /// <summary>
      /// Checks if the dialog yes button command can be executed.
      /// </summary>
      /// <param name="parameter">Command parameter.</param>
      /// <returns>If the command can be executed or not.</returns>
      protected virtual bool DialogCanYes (object parameter)
      {
         if (this.DialogContent != null)
            return this.DialogContent.CanYesExecute ();
         return true;
      }

      /// <summary>
      /// Occurs when the yes button is pressed on the dialog.
      /// </summary>
      /// <param name="parameter">Command parameter.</param>
      protected virtual void DialogYes (object parameter)
      {
         if (this.DialogContent != null)
         {
            this.DialogContent.YesExecuted ();
            if (this.DialogContent.OkToClose)
               this.DialogVisibility = Visibility.Collapsed;
         }
      }

      /// <summary>
      /// Checks if the dialog no button command can be executed.
      /// </summary>
      /// <param name="parameter">Command parameter.</param>
      /// <returns>If the command can be executed or not.</returns>
      protected virtual bool DialogCanNo (object parameter)
      {
         if (this.DialogContent != null)
            return this.DialogContent.CanNoExecute ();
         return true;
      }

      /// <summary>
      /// Occurs when the no button is pressed on the dialog.
      /// </summary>
      /// <param name="parameter">Command parameter.</param>
      protected virtual void DialogNo (object parameter)
      {
         if (this.DialogContent != null)
         {
            this.DialogContent.NoExecuted ();
            if (this.DialogContent.OkToClose)
               this.DialogVisibility = Visibility.Collapsed;
         }
      }

      /// <summary>
      /// Checks if the dialog cancel button command can be executed.
      /// </summary>
      /// <param name="parameter">Command parameter.</param>
      /// <returns>If the command can be executed or not.</returns>
      protected virtual bool DialogCanCancel (object parameter)
      {
         if (this.DialogContent != null)
            return this.DialogContent.CanCancelExecute ();
         return true;
      }

      /// <summary>
      /// Occurs when the cancel button is pressed on the dialog.
      /// </summary>
      /// <param name="parameter">Command parameter.</param>
      protected virtual void DialogCancel (object parameter)
      {
         if (this.DialogContent != null)
         {
            this.DialogContent.CancelExecuted ();
            if (this.DialogContent.OkToClose)
               this.DialogVisibility = Visibility.Collapsed;
         }
      }

      #endregion
   }
}
